#include <linux/init.h>
#include <linux/module.h>
#include <linux/sysctl.h>

#define MAX_SLAM_STRING_SIZE 256

static int slam_int;
static char slam_string[MAX_SLAM_STRING_SIZE];

static int slam_int_callback(ctl_table *table, int write,
	void __user *buffer, size_t *lenp, loff_t *ppos)
{
	int rc;
	int *data = table->data;

	printk("Original data = %d\n", *data);

	rc = proc_dointvec(table, write, buffer, lenp, ppos);
	if (write)
	      printk("This is write operation,now data = %d\n", *data);

	return rc;
}

static struct ctl_table slam_child[] = {
	{
		.procname = "slam_int",
		.data = &slam_int,
		.maxlen = sizeof(int),
		.mode = 0666,
		.proc_handler = slam_int_callback,
	},
	{
		.procname = "slam_string",
		.data = slam_string,
		.maxlen = MAX_SLAM_STRING_SIZE,
		.mode = 0666,
		.proc_handler = &proc_dostring,
	},
	{},
};

static struct ctl_table sysctl_ctl_table[] = {
	{
		.procname = "slam",
		.mode = 0555,
		.child = slam_child,
	},
	{},
};

static struct ctl_table_header * sysctl_header;

static __init int sysctl_example_init(void)
{
	sysctl_header = register_sysctl_table(sysctl_ctl_table);
	if (sysctl_header == NULL)
	{
		printk("register_sysctl_table failed!\n");
		return -1;
	}

	printk("sysctl_example_init success!\n");
	return 0;
}

static __exit void sysctl_example_exit(void)
{
	unregister_sysctl_table(sysctl_header);
	printk("%s success!\n",__func__);
}

module_init(sysctl_example_init);
module_exit(sysctl_example_exit);

